package jacktgq.mineSweeper;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class AlgoVisualizer {
    private AlgoFrame frame;

    private static final int BLOCK_WIDTH = 32;
    private static final int BLOCK_HEIGHT = 32;

    private MineSweeperData mineSweeperData;
    private AlgoMouseListener mouseListener;

    public AlgoVisualizer(int M, int N, int mineNumber){
        int sceneWidth = BLOCK_WIDTH * N;
        int sceneHeight = BLOCK_HEIGHT * M;

        mineSweeperData = new MineSweeperData(M, N, mineNumber);
        // 初始化视图
        EventQueue.invokeLater(() -> {
            frame = new AlgoFrame("扫雷", sceneWidth, sceneHeight, mineSweeperData);
            frame.addKeyListener(new AlgoKeyListener());
            mouseListener = new AlgoMouseListener();
            frame.canvas.addMouseListener(mouseListener);
        });
    }

    private class AlgoKeyListener extends KeyAdapter {
        @Override
        // 键盘按下事件
        public void keyReleased(KeyEvent e) {
            // 如果用户按下了回车键，重新开局
            // 如果游戏已经结束或者胜利重开
            if (mineSweeperData.isGameOver() || mineSweeperData.isWin()) {
                mineSweeperData.reset();
                // 添加点击事件
                frame.canvas.addMouseListener(mouseListener);
                frame.render(mineSweeperData);
            }
        }
    }

    private void setData(boolean isLeftClicked, int x, int y) {
        if (mineSweeperData.inArea(x, y)) {
            if (isLeftClicked) {
                // 如果点出来的是雷，游戏结束
                if (mineSweeperData.isMine[x][y]) {
                    // 移除鼠标点击事件
                    frame.canvas.removeMouseListener(mouseListener);
                    mineSweeperData.gameOver();
                    mineSweeperData.isOpen[x][y] = true;
                } else {
                    // 打开一片区域
                    mineSweeperData.open(x, y);
                }
            } else {
                // 如果已经标记过了，就去掉红旗，否则再加上红旗
                mineSweeperData.isFlag[x][y] = !mineSweeperData.isFlag[x][y];
            }

            // 判断是否赢了
            mineSweeperData.checkWin();

            frame.render(mineSweeperData);
        }
    }

    private class AlgoMouseListener extends MouseAdapter {
        @Override
        public void mouseReleased(MouseEvent event){
            Point point = event.getPoint();
            int i = point.y / BLOCK_HEIGHT;
            int j = point.x / BLOCK_WIDTH;
            // 点击了鼠标左键并且没有被标记为红旗才可以打开这个区域
            if (SwingUtilities.isLeftMouseButton(event) && !mineSweeperData.isFlag[i][j]) {
                setData(true, i, j);
            }
            // 点击了鼠标右键并且没有被打开才可以标记红旗
            else if (SwingUtilities.isRightMouseButton(event) && !mineSweeperData.isOpen[i][j]) {
                setData(false, i, j);
            }
        }
    }

    public static void main(String[] args) {
        AlgoVisualizer visualizer = new AlgoVisualizer(20, 30, 30);
    }
}
